/**
 * 
 */
package ar.edu.utn.frsf.cidisi.ginet.generation.elementsestructure.elementstemplate;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.pnml.tools.epnk.pnmlcoremodel.Coordinate;
import org.pnml.tools.epnk.pnmlcoremodel.NodeGraphics;
import org.pnml.tools.epnk.pnmlcoremodel.PlaceNode;
import org.pnml.tools.epnk.pnmlcoremodel.PnmlcoremodelFactory;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.Declaration;

import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Arc;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Page;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Place;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.RefPlace;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Transition;
import ar.edu.utn.frsf.cidisi.ginet.generation.elementsestructure.TreeInterface;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Termination;


/**
 * @author Neri
 *
 */
public class InteractionProtocolStructure extends ChoreographyStructure {
	
	EList<TreeInterface> treeList;
	
	private EList<Declaration> ginetDeclarations;
	
	public InteractionProtocolStructure(EList<TreeInterface> treeList, EList<Declaration> ginetDeclarations){		
		super();
		
		this.treeList = treeList;
		
		this.fillVarDeclAndNameSort(ginetDeclarations);
		
		this.ginetDeclarations = ginetDeclarations;
	}
	
	public Page createInteractionProtocol(int pos){
		EList<Page> pages = new BasicEList<Page>();
		Page pageReturn = ChoreographyStructure.createPage("UpColbPipGinet", 4, 1, "UpColbPipGinet", -9, -39);
		
		int isTerminationRoot = this.getTerminationRoot(this.treeList);
		boolean hasplaceTermination = this.getTerminationPlace(this.treeList);
		Place placeTermination = this.createPlace("Termination", 240 ,
				(float) 114.5, "Termination", -4, -9,
				this.getVarDec("gi"), 6, 21, false, "1");
		
		if (this.treeList.size() > 0) {
			Transition transition = null;
			//for (int i = 0; i < this.treeList.size(); i++) {
			int i = 0;
			for (TreeInterface tree : this.treeList) {
				if(!(tree.getRoot().getNode() instanceof Termination)){
					int k = i + 1;
					Place place = null;
					Place place2 = null;
	
					Arc arc = null;
					Arc arc1 = null;
	
					Page page = null;
	
					place = this.createPlace("InIP" + k, (80 + (320 * (i))),
							(float) 114.5, "InIP" + k, -4, -9,
							this.getVarDec("gi"), 6, 21, true, "1");
					if (transition != null) {
						arc = this.createArc("", this.getVarDec("gi"), -9, -19,
								transition, place);
					}
	
	
					if ((i + 1) < (this.treeList.size() - isTerminationRoot)) {
						place2 = this.createPlace("OutIP" + k, (240 + (320 * (i))),
								(float) 114.5, "OutIP" + k, -4, -9,
								this.getVarDec("gi"), 6, 21, false, "1");
						transition = this.createTransition("IPTransition" + k,
								(320 + (320 * i)), (float) 114.5, "IPTransition" + k,
								-9, -4, "1", "1", null);
						arc1 = this.createArc("", this.getVarDec("gi"), -9, -19,
								place2, transition);
					} else {
						if(hasplaceTermination && isTerminationRoot == 0){
							place2 = this.createPlace("OutIP" + k, (240 + (320 * (i))),
									(float) 114.5, "OutIP" + k, -4, -9,
									this.getVarDec("gi"), 6, 21, false, "1");
						}else{
							NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
									.createNodeGraphics();
	
							Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
									.createCoordinate();
	
							coordinate.setX(40);
							coordinate.setY(40);
	
							graphics.setDimension(coordinate);
	
							Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
									.createCoordinate();
	
							coordinate1.setX(240 + (320 * (i)));
							coordinate1.setY((float) 114.5);
							
							graphics.setPosition(coordinate1);
							
							placeTermination.setGraphics(graphics);	
							place2 = placeTermination;
						}
	
						transition = null;
					}
	
					page = this.getPageForElement(
								this.treeList.get(i).getRoot(), this.treeList.get(i),
									k, place, place2, ginetDeclarations, placeTermination);
	
					if (page != null) {
	
						NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
								.createNodeGraphics();
	
						Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
								.createCoordinate();
	
						coordinate.setX(40);
						coordinate.setY(40);
	
						graphics.setDimension(coordinate);
	
						Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
								.createCoordinate();
	
						coordinate1.setX((160 + (320 * i)));
						coordinate1.setY((float) 114.5);
	
						graphics.setPosition(coordinate1);
	
						page.setGraphics(graphics);
	
						pages.add(page);
	
						if (place != null) {
							pageReturn.getObject().add(place);
						}
						if (arc != null) {
							pageReturn.getObject().add(arc);
						}
						if (arc1 != null) {
							pageReturn.getObject().add(arc1);
						}
						if (place2 != null) {
							pageReturn.getObject().add(place2);
						}
						if (transition != null) {
							pageReturn.getObject().add(transition);
						}
					}
					i++;
				}
			}
			pageReturn.getObject().addAll(pages);
		} else {
			Page page = this.getPageForElement(
						this.treeList.get(0).getRoot(), this.treeList.get(0), pos,
						null, null, ginetDeclarations, placeTermination);

			pageReturn.getObject().addAll(page.getArcs());
			pageReturn.getObject().addAll(page.getPlaces());
			pageReturn.getObject().addAll(page.getTransitions());
			pageReturn.getObject().addAll(page.getRefPlaces());
			pageReturn.getObject().addAll(page.getPages());
		}
		
		return pageReturn;
	}
	
	/**
	 * @param treeList2
	 * @return
	 *
	 * @author Neri
	 */
	private boolean getTerminationPlace(EList<TreeInterface> treeList2) {
		for (TreeInterface treeInterface : treeList2) {
			if(treeInterface.hasTermination()){
				return true;
			}
		}
		return false;
	}
	
	private int getTerminationRoot(EList<TreeInterface> treeList2) {
		int value = 0;
		for (TreeInterface treeInterface : treeList2) {
			if(treeInterface.getRoot().getNode() instanceof Termination){
				return 1;
			}
		}
		return value;
	}

	public EList<Declaration> getGinetDeclarations(){
		return this.ginetDeclarations;
	}

}
